<?php
/**
 * Created by PhpStorm.
 * User: jwb
 * Date: 2020/9/15
 * Time: 11:23
 */

namespace App\Services;

use App\Document;
use App\Extensions\Actions\Document\CacheStaticFileToLocalPost;
use App\Extensions\Actions\Document\DocumentUploadImagePost;
use App\Extensions\Actions\Document\DocumentUploadPost;
use App\Extensions\Actions\Document\DocumentUploadSettingPost;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Grid\Tools\Selector;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;

class DocumentService extends BaseService
{
    const CACHE_DISK = 'public';

    /**
     * @param $role
     * @return Grid
     */
    public function gridColumns($role = 0): Grid
    {
        $user = Admin::user();
        $grid = new Grid(new Document());
        $grid->model()->collection(function (Collection $collection) {
            foreach ($collection as $key => $item) {
                $item->index = $key + 1;
            }
            return $collection;
        });
        $grid->model()->where('type', 0)
            ->when($role == 1, function (Builder $builder) {
                $builder->where('department_id', 0);
            }, function (Builder $builder) use ($user) {
                $builder->whereIn('department_id', [0, $user['department_id']]);
            })
            ->orderByDesc('id');
        $grid->column('index', '序号')->display(function ($val) {
            return '&nbsp;&nbsp;' . $val;
        });
        $grid->column('name', '名称')->display(function ($val) {
            return '<i class="fa fa-download"></i>' . $val;
        })->link(function (Document $model) {
            return file_preview_url($model['path'], $model['name']);
        });
        $grid->column('creator.name', '创建人');
        $grid->column('created_at', '创建时间');
        $grid->actions(function (Grid\Displayers\Actions $actions) use ($role) {
            $actions->disableView();
            $actions->disableEdit();
            if ($role != 1 && !$actions->row->department_id) {
                $actions->disableDelete();
            }
        });
        if ($role) {
            $grid->tools(function (Grid\Tools $tools) {
                $tools->prepend(new DocumentUploadPost());
            });
        } else {
            $grid->disableActions();
        }
        $grid->disableBatchActions();
        $grid->disableFilter();
        $grid->disableExport();
        $grid->disableCreateButton();
        $grid->quickSearch('name')->placeholder('关键字');
        return $grid;
    }

    /**
     * @return Grid
     */
    public function gridSettingColumns(): Grid
    {
        $grid = new Grid(new Document());
        $grid->model()->where('type', '>', 0)->orderByDesc('id');
        $grid->column('name', '名称')->display(function ($val) {
            return '<i class="fa fa-download"></i>' . $val;
        })->link(function (Document $model) {
            return file_preview_url($model['path'], $model['name'], 'show');
        });
        $grid->column('slug', '标识')->using(Document::slugOptions());
        $grid->column('path', '路径')->copyable();
        $grid->column('created_at', '创建时间');
        $grid->actions(function (Grid\Displayers\Actions $actions) {
            $actions->disableView();
            $actions->disableEdit();
        });
        $grid->tools(function (Grid\Tools $tools) {
            $tools->prepend(new DocumentUploadSettingPost());
            $tools->prepend(new DocumentUploadImagePost());
            $tools->prepend(new CacheStaticFileToLocalPost());
        });
        $grid->batchActions(function (Grid\Tools\BatchActions $actions) {
            $actions->disableDeleteAndHodeSelectAll();
        });
        $grid->disableFilter();
        $grid->disableExport();
        $grid->disableCreateButton();
        $grid->quickSearch('name')->placeholder('关键字');
        $grid->selector(function (Selector $selector) {
            $selector->selectOne('type', '类型', [1 => '附件', 2 => '图片'], function ($query, $value) {
                $query->where('type', $value);
            });
        });
        return $grid;
    }

    /**
     * @return Filesystem
     */
    public function getCacheStorage(): Filesystem
    {
        return Storage::disk(self::CACHE_DISK);
    }

    public function getStorage(): Filesystem
    {
        return Storage::disk(config('admin.upload.disk'));
    }


    /**
     * @param UploadedFile $file
     * @param array $data
     * @param int $creator_id
     * @return void
     * @throws FileNotFoundException
     */
    public function addDocument(UploadedFile $file, array $data, int $creator_id = 0)
    {
        $data['department_id'] = data_get($data, 'department_id', 0);
        $data['creator_id'] = data_get($data, 'creator_id', $creator_id);
        $data['type'] = data_get($data, 'type', 0);
        $data['name'] = data_get($data, 'name', $file->getClientOriginalName());
        $data['path'] = admin_store($file, 'uploads/files');
        if ($data['type'] > 0) {
            $this->addCacheFileToLocal($data['path']);
        }
        Document::query()->create($data);
        Document::forgetCache();
    }

    /**
     * @throws FileNotFoundException
     */
    public function addCacheFileToLocal($path)
    {
        $storage = $this->getStorage();
        if ($storage->exists($path)) {
            $this->getCacheStorage()->put($path, $storage->get($path));
        }
    }

    /**
     * @return void
     */
    public function cacheStaticFileToLocal()
    {
        $storage = $this->getCacheStorage();
        Document::query()
            ->where('type', '>', 0)
            ->pluck('path', 'path')
            ->map(function ($path) use ($storage) {
                if (!$storage->exists($path)) {
                    $this->addCacheFileToLocal($path);
                }
            });
        Document::forgetCache();
    }

    /**
     * @param $slug
     * @param $default
     * @return mixed|string
     */
    public function settingImageUrl($slug, $default = '')
    {
        $model = Document::allSettingCollection()->where('slug', $slug)->first();
        if ($model && $path = $model->path) {
            try {
                $storage = $this->getCacheStorage();
                if (!$storage->exists($path)) {
                    $this->addCacheFileToLocal($path);
                    if (!$storage->exists($path)) {
                        return $default;
                    }
                }
                return url($path);
            } catch (\Exception $e) {
            }
        }
        return $default;
    }

}
